package org.hanbo.code.repository.action;

import java.util.List;

import org.hanbo.code.repository.exception.CodeSnippetActionNotAuthorizedException;
import org.hanbo.code.repository.exception.CodeSnippetNotFoundException;
import org.hanbo.code.repository.exception.ErrorDescription;
import org.hanbo.code.repository.persistence.entity.CodeSnippet;
import org.hanbo.code.repository.persistence.entity.CodeSnippetDAO;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;

public class UpdateCodeSnippetAction
	extends CodeSnippetActionBase
{
	private static final long serialVersionUID = -6135067821210730101L;
	
	private String idType;
	private ErrorDescription errorDescription;
	private String authorEmailField;
	
	private CodeSnippet codeSnippetToUpdate;
	
	public void setIdType(String idType)
	{
		this.idType = idType;
	}
	
	public void validate()
	{
		if (subjectField == null || subjectField.length() <= 0)
		{
			addFieldError("subjectField", "The subject field can't be empty");
		}
		if (codeSnippetField == null || codeSnippetField.length() <= 0)
		{
			addFieldError("codeSnippetField", "The code snippet field can't be empty");
		}
		if (relatedCommentsField == null || relatedCommentsField.length() <= 0)
		{
			addFieldError("relatedCommentsField", "The comments field can't be empty");
		}
	}
	
	public String execute()
	{
		if (!checkLogin())
		{
			return super.getCurrentStageValue();
		}
		
		if (!super.checkRegistration())
		{
			return super.getCurrentStageValue();
		}
		String loggedInUserEmail = super.getRegisteredUser().getUserEmail().getEmail();
		
		try
		{
			if (idType == null || idType.length() <= 0 || snippetId <= 0)
			{
				throw new IllegalArgumentException("IdType or snippetId is invalid");
			}
			Key codeSnippetId = KeyFactory.createKey(this.idType, this.snippetId);
			
			CodeSnippetDAO codeSnippetRetriever = new CodeSnippetDAO();
			try
			{
				codeSnippetRetriever.acquirePersistenceManager();
				this.codeSnippetToUpdate
					= codeSnippetRetriever.getCodeSnippetById(codeSnippetId);
				if (this.codeSnippetToUpdate == null)
				{
					throw new CodeSnippetNotFoundException(this.snippetId);
				}
				
				this.authorEmailField = this.codeSnippetToUpdate.getAuthorEmail();
				if (!this.authorEmailField.equals(loggedInUserEmail))
				{
					throw new CodeSnippetActionNotAuthorizedException(
						"Modify code snippet that does not belong to you."
						);
				}
				
				this.codeSnippetToUpdate.setAvailabilityToPublic(this.viewByPublic);
				this.codeSnippetToUpdate.setCodeComments(this.relatedCommentsField);
				this.codeSnippetToUpdate.setCodeSnippet(this.codeSnippetField);
				List<String> keywords = CodeSnippet.convertStringToArrayList(this.keywordsField);
				this.codeSnippetToUpdate.setKeywords(keywords);
				this.codeSnippetToUpdate.setLanguageType(this.languageField);
				this.codeSnippetToUpdate.setReferenceLink(this.referenceUrlField);
				List<String> methods = CodeSnippet.convertStringToArrayList(this.relatedMethodsField);
				this.codeSnippetToUpdate.setRelatedMethods(methods);
				this.codeSnippetToUpdate.setSubject(this.subjectField);
			}
			catch (Exception e)
			{
				throw e;
			}
			finally
			{
				codeSnippetRetriever.releasePersistenceManager();
			}
		}
		catch(CodeSnippetNotFoundException e)
		{
			errorDescription = new ErrorDescription(e);
			return ERROR;
		}
		catch(Exception e)
		{
			errorDescription = new ErrorDescription(1000, e);
			return ERROR;
		}
		
		return SUCCESS;
	}
	
	public String getNextActionPage()
	{
		return "/RetrieveCodeSnippetById?type=CodeSnippet&id=" + this.snippetId;
	}

	public String getRedirectDisplayMessage()
	{
		return "Code Snippet [id: " + this.snippetId + ", Subject: " + this.subjectField + "] was saved successfully.";
	}
	
    public String getRedirectLogin()
    {
    	return super.createLogInLink("../index.action");
    }

	public ErrorDescription getErrorDescription()
	{
		return errorDescription;
	}
}